//
//  GlobalUtil.m
//  SZYH2
//
//  Created by ZZB on 13-7-16.
//  Copyright (c) 2013年 JMU. All rights reserved.
//

#include <sys/sysctl.h>
#include <mach/mach.h>
#import <QuartzCore/QuartzCore.h>
#import "sys/utsname.h"
#import "GlobalUtil.h"
#import "StringUtil.h"
#import <objc/runtime.h>
#import "NSString+Additions.h"

@implementation GlobalUtil

#pragma mark - Language

+ (BOOL)isNull:(id)object
{
    if (object == nil || [object isEqual:[NSNull null]]) {
        return YES;
    }
    
    return NO;
}

+ (BOOL)isNotNull:(id)object
{
    return (![GlobalUtil isNull:object]);
}

+ (BOOL)isEmptyArray:(NSArray *)array {
    if (array == nil || [array isEqual:[NSNull null]] || array.count <= 0) {
        return YES;
    }
    
    return NO;
}

+ (NSURL *)urlFromString:(NSString *)string
{
    if (string == nil) {
        return nil;
    }
    
    NSString *escape = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //URL编码
    return [NSURL URLWithString:escape];
}

+ (BOOL)isOrientationVertical
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    return [GlobalUtil isOrientationVertical:orientation];
}

+ (BOOL)isOrientationVertical:(UIInterfaceOrientation)orientation
{
    if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
        return YES;
    }
    
    return NO;
}

+ (UIInterfaceOrientation)currentOrientation
{
    return [UIApplication sharedApplication].statusBarOrientation;
}

+ (NSString *)documentPath
{
    NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    if (docPath == nil) {
        return @"";
    }
    
    return docPath;
}

+ (BOOL)isDevicePad
{
    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
}

+ (NSString *)appVersion
{
    return [[NSBundle mainBundle] objectForInfoDictionaryKey: @"CFBundleShortVersionString"];
}

+ (NSString *)buildVersion
{
    return [[NSBundle mainBundle] objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleVersionKey];
}

+ (NSString*)deviceUUID
{
    return @"dummy uuid";   //TODO:
}

/*
+ (NSString*)deviceID
{
    NSString *udid = [OpenUDID value];
    if ([StringUtil isEmpty:udid]) {
        return @"EMPTY_ID";
    }
    
    return udid;
}*/

+ (NSString*)deviceString
{
    // 需要
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
    
    if ([deviceString isEqualToString:@"iPhone1,1"])    return @"iPhone 1G";
    if ([deviceString isEqualToString:@"iPhone1,2"])    return @"iPhone 3G";
    if ([deviceString isEqualToString:@"iPhone2,1"])    return @"iPhone 3GS";
    if ([deviceString isEqualToString:@"iPhone3,1"])    return @"iPhone 4";
    if ([deviceString isEqualToString:@"iPhone4,1"])    return @"iPhone 4S";
    if ([deviceString isEqualToString:@"iPhone5,2"])    return @"iPhone 5";
    if ([deviceString isEqualToString:@"iPhone3,2"])    return @"Verizon iPhone 4";
    if ([deviceString isEqualToString:@"iPod1,1"])      return @"iPod Touch 1G";
    if ([deviceString isEqualToString:@"iPod2,1"])      return @"iPod Touch 2G";
    if ([deviceString isEqualToString:@"iPod3,1"])      return @"iPod Touch 3G";
    if ([deviceString isEqualToString:@"iPod4,1"])      return @"iPod Touch 4G";
    if ([deviceString isEqualToString:@"iPad1,1"])      return @"iPad";
    if ([deviceString isEqualToString:@"iPad2,1"])      return @"iPad 2 (WiFi)";
    if ([deviceString isEqualToString:@"iPad2,2"])      return @"iPad 2 (GSM)";
    if ([deviceString isEqualToString:@"iPad2,3"])      return @"iPad 2 (CDMA)";
    if ([deviceString isEqualToString:@"i386"])         return @"Simulator";
    if ([deviceString isEqualToString:@"x86_64"])       return @"Simulator";

    return deviceString;
}

+ (BOOL)isIPhone5
{
//    NSString *strDevice = [GlobalUtil deviceString];
//    return [strDevice isEqualToString:@"iPhone 5"];
    CGSize size = [UIScreen mainScreen].bounds.size;
    
    if (size.height > 480) {
        return YES;
    }
    
    return NO;
}

#pragma mark - View / Widgets

+ (id)loadViewFromClass:(Class)viewClass
{
    return [GlobalUtil loadViewFromClass:viewClass withIndex:0];
}

+ (id)loadViewFromClass:(Class)viewClass withIndex:(int)index
{
    NSString *strNib = NSStringFromClass(viewClass);
    
    NSArray *views = [[NSBundle mainBundle] loadNibNamed:strNib owner:nil options:nil];
    
    if (views && views.count > index) {
        
        id view = views[index];

        return view;
    }
    
    return nil;
}

+ (id)loadVCFromClass:(Class)vcClass
{
    return [[vcClass alloc] initWithNibName:NSStringFromClass(vcClass) bundle:nil];
}

#pragma mark - Image 

+ (UIImage *)scaleImage:(UIImage *)originImage toResolution:(CGSize)size
{
    if (originImage == nil) {
        return nil;
    }
    
    // 创建一个bitmap的context
    // 并把它设置成为当前正在使用的context
    UIGraphicsBeginImageContext(size);
    // 绘制改变大小的图片
    [originImage drawInRect:CGRectMake(0,0, size.width, size.height)];
    // 从当前context中创建一个改变大小后的图片
    UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();
    // 使当前的context出堆栈
    UIGraphicsEndImageContext();
    //返回新的改变大小后的图片
    return scaledImage;    
}

+ (UIImage *)scaleImage:(UIImage *)originImage toLength:(int)length
{
    if (originImage == nil) {
        return nil;
    }
    
    CGSize size = originImage.size;
    if (size.height == 0 || size.width == 0) {
        return nil;
    }

    float scale = size.height/size.width;
    
    int newWidth = 0;
    int newHeight = 0;
    
    if (size.height > size.width) {
        newHeight = length;
        newWidth = length/scale;
    }
    else {
        newWidth = length;
        newHeight = length*scale;
    }
    
    return [GlobalUtil scaleImage:originImage toResolution:CGSizeMake(newWidth, newHeight)];
}

+ (UIImage *)shrinkImage:(UIImage *)originImage toLength:(int)length
{
    if (originImage == nil) {
        return nil;
    }
    
    CGSize size = originImage.size;
    if (size.height == 0 || size.width == 0) {
        return nil;
    }

    if (size.height < length && size.width < length) {
        return originImage;
    }
    
    return [GlobalUtil scaleImage:originImage toLength:length];
}

+ (UIImage *)grayImageForImage:(UIImage *)image {
    // Adapted from this thread: http://stackoverflow.com/questions/1298867/convert-image-to-grayscale
    const int RED = 1;
    const int GREEN = 2;
    const int BLUE = 3;
    
    // Create image rectangle with current image width/height
    CGRect imageRect = CGRectMake(0, 0, image.size.width * image.scale, image.size.height * image.scale);
    
    int width = imageRect.size.width;
    int height = imageRect.size.height;
    
    // the pixels will be painted to this array
    uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));
    
    // clear the pixels so any transparency is preserved
    memset(pixels, 0, width * height * sizeof(uint32_t));
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    
    // create a context with RGBA pixels
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,
                                                 kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
    
    // paint the bitmap to our context which will fill in the pixels array
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), [image CGImage]);
    
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x];
            
            // convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
            uint32_t gray = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];
            
            // set the pixels to gray
            rgbaPixel[RED] = gray;
            rgbaPixel[GREEN] = gray;
            rgbaPixel[BLUE] = gray;
        }
    }
    
    // create a new CGImageRef from our context with the modified pixels
    CGImageRef imageRef = CGBitmapContextCreateImage(context);
    
    // we're done with the context, color space, and pixels
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(pixels);
    
    // make a new UIImage to return
    UIImage *resultUIImage = [UIImage imageWithCGImage:imageRef
                                                 scale:image.scale
                                           orientation:UIImageOrientationUp];
    
    // we're done with image now too
    CGImageRelease(imageRef);
    
    return resultUIImage;
}

+ (UIImage *)imageFromColor:(UIColor *)color
{
    CGRect rect=CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    
    UIGraphicsBeginImageContext(rect.size);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return theImage;
}

+ (UIImage *)blurImage:(UIImage *)originImage
{
    float weight[5] = {0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162};
    CGSize size = originImage.size;
    
    // Blur horizontally
    UIGraphicsBeginImageContextWithOptions(size, NO, originImage.scale);
    [originImage drawInRect:CGRectMake(0, 0, size.width, size.height) blendMode:kCGBlendModePlusLighter alpha:weight[0]];
    for (int x = 1; x < 5; ++x) {
        [originImage drawInRect:CGRectMake(x, 0, size.width, size.height) blendMode:kCGBlendModePlusLighter alpha:weight[x]];
        [originImage drawInRect:CGRectMake(-x, 0, size.width, size.height) blendMode:kCGBlendModePlusLighter alpha:weight[x]];
    }
    
    UIImage *horizBlurredImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    // Blur vertically
    UIGraphicsBeginImageContextWithOptions(size, NO, originImage.scale);
    [horizBlurredImage drawInRect:CGRectMake(0, 0, size.width, size.height) blendMode:kCGBlendModePlusLighter alpha:weight[0]];
    for (int y = 1; y < 5; ++y) {
        [horizBlurredImage drawInRect:CGRectMake(0, y, size.width, size.height) blendMode:kCGBlendModePlusLighter alpha:weight[y]];
        [horizBlurredImage drawInRect:CGRectMake(0, -y, size.width, size.height) blendMode:kCGBlendModePlusLighter alpha:weight[y]];
    }
    
    UIImage *blurredImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return blurredImage;
}

#pragma mark - UI

+ (UIColor *)changeColor:(UIColor *)orginColor withAlpha:(float)newAlpha
{
    if (orginColor == nil) {
        return nil;
    }
    
    CGFloat red, green, blue, alpha;
    [orginColor getRed:&red green:&green blue:&blue alpha:&alpha];
    
    return [UIColor colorWithRed:red green:green blue:blue alpha:newAlpha];
}

+ (void)borderForView:(UIView *)view withColor:(UIColor *)color withSize:(int)size
{
    view.layer.borderColor = [color CGColor];
    view.layer.borderWidth = size;
}

+ (void)cornerForView:(UIView *)view withSize:(int)size
{
    view.layer.cornerRadius = size;
    view.layer.masksToBounds = YES;
}

+ (void)shadowForView:(UIView *)view withColor:(UIColor *)color withPosition:(CGSize)position withRadius:(int)radius withAlpha:(float)alpha;
{
    view.layer.shadowColor = [color CGColor];
    view.layer.shadowOffset = position;
    view.layer.shadowRadius = radius;
    view.layer.shadowOpacity = alpha;
}

+ (void)addSubview:(UIView *)subview toParent:(UIView *)view marginLeft:(int)leftMargin marginTop:(int)topMargin
{
    if (subview == nil || view == nil) {
        return;
    }
    
    CGRect frame = subview.frame;
    frame.origin.x = leftMargin;
    frame.origin.y = topMargin;
    
    subview.frame = frame;
    subview.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
    
    [view addSubview:subview];
}

+ (void)addSubview:(UIView *)subview toParent:(UIView *)view marginLeft:(int)leftMargin marginBottom:(int)bottomMargin
{
    if (subview == nil || view == nil) {
        return;
    }
    
    CGRect frame = subview.frame;
    CGRect frameParent = view.frame;
    
    frame.origin.x = leftMargin;
    frame.origin.y = frameParent.size.height - frame.size.height - bottomMargin;
    
    subview.frame = frame;
    subview.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin;
    
    [view addSubview:subview];
}

+ (void)addSubview:(UIView *)subview toParent:(UIView *)view marginRight:(int)rightMargin marginTop:(int)topMargin
{
    if (subview == nil || view == nil) {
        return;
    }
    
    CGRect frame = subview.frame;
    CGRect frameParent = view.frame;
    
    frame.origin.x = frameParent.size.width - frame.size.width - rightMargin;
    frame.origin.y = topMargin;
    
    subview.frame = frame;
    subview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;
    
    [view addSubview:subview];
}

+ (void)addSubview:(UIView *)subview toParent:(UIView *)view marginRight:(int)rightMargin marginBottom:(int)bottomMargin
{
    if (subview == nil || view == nil) {
        return;
    }
    
    CGRect frame = subview.frame;
    CGRect frameParent = view.frame;
    
    frame.origin.x = frameParent.size.width - frame.size.width - rightMargin;
    frame.origin.y = frameParent.size.height - frame.size.height - bottomMargin;
    
    subview.frame = frame;
    subview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
    
    [view addSubview:subview];
}

+ (void)addSubview:(UIView *)subview toParent:(UIView *)view marginTop:(int)topMargin
{
    if (subview == nil || view == nil) {
        return;
    }
    
    CGRect frame = subview.frame;
    CGRect frameParent = view.frame;
    
    frame.origin.x = (frameParent.size.width - frame.size.width)/2;
    frame.origin.y = topMargin;
    
    subview.frame = frame;
    subview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
    
    [view addSubview:subview];
}

+ (void)addSubview:(UIView *)subview toParent:(UIView *)view marginBottom:(int)bottomMargin
{
    if (subview == nil || view == nil) {
        return;
    }
    
    CGRect frame = subview.frame;
    CGRect frameParent = view.frame;
    
    frame.origin.x = (frameParent.size.width - frame.size.width)/2;
    frame.origin.y = frameParent.size.height - frame.size.height - bottomMargin;
    
    subview.frame = frame;
    subview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin;
    
    [view addSubview:subview];
}

+ (void)addSubview:(UIView *)subview toParent:(UIView *)view
{
    if (subview == nil || view == nil) {
        return;
    }
    
    CGRect frame = subview.frame;
    CGRect frameParent = view.frame;
    
    frame.origin.x = (frameParent.size.width - frame.size.width)/2;
    frame.origin.y = (frameParent.size.height - frame.size.height)/2;
    
    subview.frame = frame;
    subview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
    
    [view addSubview:subview];
}

+ (void)roundForView:(UIView *)view withRadius:(float)radius
{
    if (view == nil) {
        return;
    }
    
    view.layer.cornerRadius = radius;
    view.layer.masksToBounds = YES;
}

+ (void)borderForView:(UIView *)view withColor:(UIColor *)color withWidth:(float)width
{
    if (view == nil) {
        return;
    }
    
    view.layer.borderColor = [color CGColor];
    view.layer.borderWidth = width;
}


+ (CGSize)sizeFortext:(NSString *)text withFont:(UIFont *)font constrainedToSize:(CGSize)size
{
    CGFloat stringWidth = 0.0f;
    CGFloat stringHeight = 0.0f;
    CGRect stringRect;
    if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
//        stringRect = [text boundingRectWithSize:size
//                                        options:(NSStringDrawingUsesFontLeading|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin)
//                                     attributes:@{NSFontAttributeName:font}
//                                        context:NULL];
        
        text = [[text componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\r"]] componentsJoinedByString:@""];
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
        NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName: paragraphStyle};
        stringRect = [text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:attributes context:nil];
    } else {
        CGSize stringSize;
        
        if ([text respondsToSelector:@selector(sizeWithAttributes:)])
            stringSize = [text sizeWithAttributes:@{NSFontAttributeName:[UIFont fontWithName:font.fontName size:font.pointSize]}];
        else
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
            stringSize = [text sizeWithFont:font constrainedToSize:size];
#pragma clang diagnostic pop
        
        stringRect = CGRectMake(0.0f, 0.0f, stringSize.width, stringSize.height);
    }
    stringWidth = stringRect.size.width;
    stringHeight = ceil(CGRectGetHeight(stringRect));
    return CGSizeMake(stringWidth, stringHeight);
}

+ (CGSize)sizeFortext:(NSString *)text withFont:(UIFont *)font constrainedToSize:(CGSize)size lineSpace:(CGFloat)lSpace wordSpace:(CGFloat)wSpace
{
    if (nil == text) return CGSizeMake(0, 0);
    
    CGFloat stringWidth = 0.0f;
    CGFloat stringHeight = 0.0f;
    CGRect stringRect;
    
//    NSUInteger spaceLines = [text countOccurencesOfString:@"\r"] + [text countOccurencesOfString:@"\n"] - [text countOccurencesOfString:@"\r\n"];
//    CGFloat spaceHeight = spaceLines>0?(spaceLines*font.pointSize + (spaceLines)*lSpace):0;
//    CGFloat spaceHeight = spaceLines>0?((spaceLines)*lSpace):0;
    if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
        text = [[text componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\r"]] componentsJoinedByString:@""];
//        text = [[text componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\n"]] componentsJoinedByString:@""];
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
        paragraphStyle.alignment = NSTextAlignmentLeft;
        paragraphStyle.lineSpacing = lSpace; //设置行间距
        paragraphStyle.hyphenationFactor = 1.0; // 连字符属性
        paragraphStyle.firstLineHeadIndent = 0.0;
        paragraphStyle.paragraphSpacingBefore = 0.0; // 段首行空白空间
        paragraphStyle.headIndent = 0;
        paragraphStyle.tailIndent = 0;
        paragraphStyle.alignment = NSTextAlignmentJustified;
        if (0 != lSpace) paragraphStyle.lineSpacing = lSpace;
        NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle, NSKernAttributeName:@(wSpace)};
        stringRect = [text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:attributes context:nil];
    } else {
        CGSize stringSize;
        
        if ([text respondsToSelector:@selector(sizeWithAttributes:)])
            stringSize = [text sizeWithAttributes:@{NSFontAttributeName:[UIFont fontWithName:font.fontName size:font.pointSize]}];
        else
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
            stringSize = [text sizeWithFont:font constrainedToSize:size];
#pragma clang diagnostic pop
        
        stringRect = CGRectMake(0.0f, 0.0f, stringSize.width, stringSize.height);
    }
    stringWidth = stringRect.size.width;
//    stringHeight = ceil(CGRectGetHeight(stringRect) + spaceHeight);
    stringHeight = ceil(CGRectGetHeight(stringRect));
    return CGSizeMake(stringWidth, stringHeight);
}




#pragma mark - Basic

//去掉最小值
+ (void)trimArray:(NSMutableArray *)array isMax:(BOOL)isMax
{
    if (array == nil || array.count < 2) {
        return;
    }
    
    int index = 0;
    NSNumber *num = array[index];
    
    for (int i=0; i<array.count; i++) {
        
        NSNumber *tmp = array[i];
        
        if (isMax) {
            if (tmp.doubleValue > num.doubleValue) {
                index = i;
                num = array[i];
            }
        }
        else {
            if (tmp.doubleValue < num.doubleValue) {
                index = i;
                num = array[i];
            }
        }
    }
    
    [array removeObjectAtIndex:index];
}

+ (void)trimArrayMaxMin:(NSMutableArray *)array
{
    if (array == nil) {
        return;
    }
    
    [GlobalUtil trimArray:array isMax:YES];
    [GlobalUtil trimArray:array isMax:NO];
}

+ (NSString *)debugArray:(NSArray *)array
{
    if (array == nil) {
        return @"";
    }
    
    NSMutableString *msg = [NSMutableString stringWithString:@"Array: "];
    
    for (int i=0; i<array.count; i++) {
        NSNumber *num = array[i];
        
        [msg appendFormat:@"%.3f, ", num.doubleValue];
    }
    
    return msg;
}

+ (void)distinctAddOject:(id)object intoArray:(NSMutableArray *)array
{
    if (object == nil || array == nil) {
        return;
    }
    
    for (int i=0; i<array.count; i++) {
        if (array[i] == object) {
            return;
        }
    }
    
    [array addObject:object];
}

+ (NSArray *)randomArray:(NSArray *)array
{
    if (array == nil) {
        return nil;
    }
    
    NSMutableArray *results = [NSMutableArray arrayWithArray:array];
    NSUInteger i = [results count];
    while(--i > 0) {
        int j = rand() % (i+1);
        [results exchangeObjectAtIndex:i withObjectAtIndex:j];
    }
    
    return [NSArray arrayWithArray:results];
}

+ (double)availableMemory
{
	@try {
		vm_statistics_data_t vmStats;
		mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
		kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount);
		
		if(kernReturn != KERN_SUCCESS) {
			return NSNotFound;
		}
		
		return ((vm_page_size * vmStats.free_count) / 1024.0) / 1024.0;
	}
	@catch(NSException *e) {
		NSLog(@"AvailableMemory Catch Error");
	}
    @finally {
    }
    
	return -1;
}


#pragma mark - JSON

+ (NSString *)jsonStringFromObject:(id)object {
    NSError *error = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object
                                                       options:NSJSONWritingPrettyPrinted
                                                         error:&error];
    NSString *jsonString = @"";
    
    if (jsonData && [jsonData length] && error == nil){
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    
    return (jsonString?:@"");
}

+ (id)objectFromJsonString:(NSString *)jsonString {
    NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    
    NSError *error = nil;
    id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
    return object;
}

//对象 -> 字典
+ (NSDictionary *)getObjectData:(id)obj
{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    unsigned int propsCount;
    objc_property_t *props = class_copyPropertyList([obj class], &propsCount);
    for(int i = 0;i < propsCount; i++)
    {
        objc_property_t prop = props[i];
        
        NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];
        id value = [obj valueForKey:propName];
        if(value == nil)
        {
            value = [NSNull null];
        }
        else
        {
            value = [self getObjectInternal:value];
        }
        [dic setObject:value forKey:propName];
    }
    return dic;
}
//对象 -> JSON
+ (NSData *)getJSON:(id)obj options:(NSJSONWritingOptions)options error:(NSError**)error
{
    return [NSJSONSerialization dataWithJSONObject:[self getObjectData:obj] options:options error:error];
}
//打印对象中的字段
+ (void)print:(id)obj
{
    NSLog(@"%@", [self getObjectData:obj]);
}

+ (id)getObjectInternal:(id)obj
{
    if([obj isKindOfClass:[NSString class]]
       || [obj isKindOfClass:[NSNumber class]]
       || [obj isKindOfClass:[NSNull class]])
    {
        return obj;
    }
    
    if([obj isKindOfClass:[NSArray class]])
    {
        NSArray *objarr = obj;
        NSMutableArray *arr = [NSMutableArray arrayWithCapacity:objarr.count];
        for(int i = 0;i < objarr.count; i++)
        {
            [arr setObject:[self getObjectInternal:[objarr objectAtIndex:i]] atIndexedSubscript:i];
        }
        return arr;
    }
    
    if([obj isKindOfClass:[NSDictionary class]])
    {
        NSDictionary *objdic = obj;
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:[objdic count]];
        for(NSString *key in objdic.allKeys)
        {
            [dic setObject:[self getObjectInternal:[objdic objectForKey:key]] forKey:key];
        }
        return dic;
    }
    return [self getObjectData:obj];
}

+ (NSString *)parseString:(id)value {
    if ([GlobalUtil isNull:value]) {
        return @"";
    }
    
    if ([value isKindOfClass:[NSNumber class]]) {
        NSNumber *num = value;
        return num.stringValue;
    }
    
    if ([value isKindOfClass:[NSString class]] == NO) {
        return @"";
    }
    
    return value;
}

+ (int)parseInt:(id)object
{
    int v = 0;
    if (object == nil) {
        return v;
    }
    
    if ([object isKindOfClass:[NSNumber class]]) {
        NSNumber *number = (NSNumber *)object;
        return number.intValue;
    }
    
    if ([object isKindOfClass:[NSString class]]) {
        @try {
            NSString *string = (NSString *)object;
            v = string.intValue;
        }
        @catch (NSException *exception) {
            ;
        }
        
        return v;
    }
    
    return v;
}

+ (long)parseLong:(id)object {
    long v = 0;
    if (object == nil) {
        return v;
    }
    
    if ([object isKindOfClass:[NSNumber class]]) {
        NSNumber *number = (NSNumber *)object;
        return number.longValue;
    }
    
    if ([object isKindOfClass:[NSString class]]) {
        @try {
            NSString *string = (NSString *)object;
            v = (long)string.longLongValue;
        }
        @catch (NSException *exception) {
            ;
        }
        
        return v;
    }
    
    return v;
}

+ (long long)parseLongLong:(id)object {
    long long v = 0;
    if (object == nil) {
        return v;
    }
    
    if ([object isKindOfClass:[NSNumber class]]) {
        NSNumber *number = (NSNumber *)object;
        return number.longLongValue;
    }
    
    if ([object isKindOfClass:[NSString class]]) {
        @try {
            NSString *string = (NSString *)object;
            v = string.longLongValue;
        }
        @catch (NSException *exception) {
            ;
        }
        
        return v;
    }
    
    return v;
}

+ (NSInteger)parseInteger:(id)object {
    NSInteger v = 0;
    if (object == nil) {
        return v;
    }
    
    if ([object isKindOfClass:[NSNumber class]]) {
        NSNumber *number = (NSNumber *)object;
        return number.integerValue;
    }
    
    if ([object isKindOfClass:[NSString class]]) {
        @try {
            NSString *string = (NSString *)object;
            v = string.integerValue;
        }
        @catch (NSException *exception) {
            ;
        }
        
        return v;
    }
    
    return v;
}

+ (float)parseFloat:(id)object
{
    float v = 0;
    if (object == nil) {
        return v;
    }
    
    if ([object isKindOfClass:[NSNumber class]]) {
        NSNumber *number = (NSNumber *)object;
        return number.floatValue;
    }
    
    if ([object isKindOfClass:[NSString class]]) {
        @try {
            NSString *string = (NSString *)object;
            v = string.floatValue;
        }
        @catch (NSException *exception) {
            ;
        }
        
        return v;
    }
    
    return v;
}

+ (double)parseDouble:(id)object {
    double v = 0;
    if (object == nil) {
        return v;
    }
    
    if ([object isKindOfClass:[NSNumber class]]) {
        NSNumber *number = (NSNumber *)object;
        return number.doubleValue;
    }
    
    if ([object isKindOfClass:[NSString class]]) {
        @try {
            NSString *string = (NSString *)object;
            v = string.doubleValue;
        }
        @catch (NSException *exception) {
            ;
        }
        
        return v;
    }
    
    return v;
}

+ (BOOL)parseBool:(id)object
{
    BOOL v = NO;
    if (object == nil) {
        return v;
    }
    
    if ([object isKindOfClass:[NSNumber class]]) {
        NSNumber *number = (NSNumber *)object;
        return number.boolValue;
    }
    
    if ([object isKindOfClass:[NSString class]]) {
        @try {
            NSString *string = (NSString *)object;
            v = string.boolValue;
        }
        @catch (NSException *exception) {
            ;
        }
        
        return v;
    }
    
    return v;
}

#pragma mark - Date & Time

+ (BOOL)isTime:(NSDate *)time between:(NSDate *)startTime and:(NSDate *)endTime
{
    if (time == nil) {
        return NO;
    }
    
    if (startTime == nil || endTime == nil) {
        return NO;
    }
    
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSInteger unitFlags = NSYearCalendarUnit |
                            NSMonthCalendarUnit |
                            NSDayCalendarUnit |
                            NSWeekdayCalendarUnit |
                            NSHourCalendarUnit |
                            NSMinuteCalendarUnit |
                            NSSecondCalendarUnit;
    NSDateComponents *comps = [cal components:unitFlags fromDate:time];
    NSInteger hour = [comps hour];
    NSInteger min = [comps minute];
    
    NSDateComponents *compsStart = [cal components:unitFlags fromDate:startTime];
    NSInteger hourStart = [compsStart hour];
    NSInteger minStart = [compsStart minute];
    
    NSDateComponents *compsEnd = [cal components:unitFlags fromDate:endTime];
    NSInteger hourEnd = [compsEnd hour];
    NSInteger minEnd = [compsEnd minute];
    
    float t = ((NSString *)[NSString stringWithFormat:@"%d.%d", (int)hour, (int)min]).floatValue;
    float t1 = ((NSString *)[NSString stringWithFormat:@"%d.%d", (int)hourStart, (int)minStart]).floatValue;
    float t2 = ((NSString *)[NSString stringWithFormat:@"%d.%d", (int)hourEnd, (int)minEnd]).floatValue;
    
    if (t1 <= t2) {
        if (t >= t1 && t <= t2) {
            return YES;
        } else {
            return NO;
        }
    }
    else {
        if (t >= t1 || t <= t2) {
            return YES;
        } else {
            return NO;
        }
    }
}

+ (NSDate *)createDate:(NSDate *)date withTime:(NSDate *)time
{
    if (date == nil && time == nil) {
        return nil;
    }
    if (date == nil) {
        return time;
    }
    if (time == nil) {
        return date;
    }
    
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSInteger unitFlags = NSCalendarUnitYear |
    NSCalendarUnitMonth |
    NSCalendarUnitDay |
    NSCalendarUnitWeekday |
    NSCalendarUnitHour |
    NSCalendarUnitMinute |
    NSCalendarUnitSecond;
    
    //获取date的日期：
    NSDateComponents *compsDate = [cal components:unitFlags fromDate:date];
    NSInteger year = [compsDate year];
    NSInteger mon = [compsDate month];
    NSInteger day = [compsDate day];
    
    //获取time的时间：
    NSDateComponents *compsTime = [cal components:unitFlags fromDate:time];
    NSInteger hour = [compsTime hour];
    NSInteger minute = [compsTime minute];
    NSInteger second = [compsTime second];
    
    //组成新的时间：
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    [comps setYear:year];
    [comps setMonth:mon];
    [comps setDay:day];
    [comps setHour:hour];
    [comps setMinute:minute];
    [comps setSecond:second];
    
    return [cal dateFromComponents:comps];
}

+ (NSInteger)createDateStamp:(NSInteger)dateStamp withTimeStamp:(NSInteger)timeStamp
{
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSInteger unitFlags = NSCalendarUnitYear |
    NSCalendarUnitMonth |
    NSCalendarUnitDay |
    NSCalendarUnitWeekday |
    NSCalendarUnitHour |
    NSCalendarUnitMinute |
    NSCalendarUnitSecond;
    
    // 获取dateStamp的年月日
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:dateStamp];
    NSDateComponents *compsDate = [cal components:unitFlags fromDate:date];
    NSInteger year = [compsDate year];
    NSInteger mon = [compsDate month];
    NSInteger day = [compsDate day];
    
    // 获取timeStamp的时分秒
    NSDate *time = [NSDate dateWithTimeIntervalSince1970:timeStamp];
    NSDateComponents *compsTime = [cal components:unitFlags fromDate:time];
    NSInteger hour = [compsTime hour];
    NSInteger minute = [compsTime minute];
    NSInteger second = [compsTime second];
    
    // 组成新的时间
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    [comps setYear:year];
    [comps setMonth:mon];
    [comps setDay:day];
    [comps setHour:hour];
    [comps setMinute:minute];
    [comps setSecond:second];
    
    NSDate *newDate = [cal dateFromComponents:comps];
    return [[NSNumber numberWithDouble:[newDate timeIntervalSince1970]] integerValue];
}



#pragma mark - Functional

//将VC弹出到某层
+ (void)dismissToViewController:(UIViewController *)toVC withRootVC:(UIViewController *)rootVC withAnimation:(BOOL)isAnimation
{
    BOOL found = false;
    NSMutableArray *vcArray = [[NSMutableArray alloc] init];
    
    while (rootVC && rootVC.presentedViewController) {
        rootVC = rootVC.presentedViewController;
        if (rootVC == toVC) {
            found = true;
        }
        
        [vcArray addObject:rootVC];
    }
    
    if (found == false || vcArray.count <= 0) {
        return;
    }
    
    for (long j=vcArray.count-1; j>=0; j--) {
        UIViewController *controller = vcArray[j];
        
        if (controller == toVC) {
            break;
        }
        
        [controller dismissViewControllerAnimated:isAnimation completion:^{}];
    }
}



//kvc 获取所有key值
+ (NSArray *)getAllIvar:(id)object
{
    NSMutableArray *array = [NSMutableArray array];
    
    unsigned int count;
    Ivar *ivars = class_copyIvarList([object class], &count);
    for (int i = 0; i < count; i++) {
        Ivar ivar = ivars[i];
        const char *keyChar = ivar_getName(ivar);
        NSString *keyStr = [NSString stringWithCString:keyChar encoding:NSUTF8StringEncoding];
        @try {
            id valueStr = [object valueForKey:keyStr];
            NSDictionary *dic = nil;
            if (valueStr) {
                dic = @{keyStr : valueStr};
            } else {
                dic = @{keyStr : @"值为nil"};
            }
            [array addObject:dic];
        }
        @catch (NSException *exception) {}
    }
    return [array copy];
}

//获得所有属性
+ (NSArray *)getAllProperty:(id)object
{
    NSMutableArray *array = [NSMutableArray array];
    
    unsigned int count;
    objc_property_t *propertys = class_copyPropertyList([object class], &count);
    for (int i = 0; i < count; i++) {
        objc_property_t property = propertys[i];
        const char *nameChar = property_getName(property);
        NSString *nameStr = [NSString stringWithCString:nameChar encoding:NSUTF8StringEncoding];
        [array addObject:nameStr];
    }
    return [array copy];
}

@end
